package com.easyfun.healthmagicbox.comm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.auth.UsernamePasswordCredentials;
import org.json.JSONObject;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.widget.Toast;

import com.easyfun.healthmagicbox.base.DatabaseAccess;
import com.easyfun.healthmagicbox.base.DatabaseAccessImplementation;
import com.easyfun.healthmagicbox.comm.json.UserJsonWrapper;
import com.easyfun.healthmagicbox.comm.json.UserToPersonsListJsonWrapper;
import com.easyfun.healthmagicbox.ormlite.DatabaseHelper;
import com.easyfun.healthmagicbox.ormlite.ServerResponseCode;
import com.easyfun.healthmagicbox.pojo.ConstantData;
import com.easyfun.healthmagicbox.pojo.PersonProfile;
import com.easyfun.healthmagicbox.pojo.User;
import com.easyfun.healthmagicbox.pojo.UserToPersons;
import com.easyfun.healthmagicbox.sync.BasicCommCallback;
import com.easyfun.healthmagicbox.sync.CommCallback;
import com.easyfun.healthmagicbox.util.ImageTools;
import com.easyfun.healthmagicbox.util.URIConverter;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;

public class UserToPersonsDownloadTask extends BaseCommTask implements Runnable,
				DatabaseAccess 
{
	private final static String LOG_TAG = UserToPersonsDownloadTask.class.getSimpleName();
	String username;
	String password;

	public UserToPersonsDownloadTask(String username,Context context,CommCallback ccb)
	{
		super(context,ccb);
		this.username = username;
		this.mcontext = context;		
	}
	
	@Override
	public DatabaseHelper getHelper(Context context) {
		return DatabaseAccessImplementation.getInstance().getHelper(mcontext);
	}

	@Override
	public void run() {

		
		JSONObject serializedObj = new JSONObject();
		String result = "";
		try {
			serializedObj.put("username", username);

			Map<String, String> parmas = new HashMap<String, String>();
			parmas.put("jsonstring", serializedObj.toString());
			result = super.uploadByHTTP(parmas, ConstantData.UserToPersonsDownURI);
			if (ServerResponseCode.parseOf(result) == ServerResponseCode.FAILED) {

				ccb.setCommResult(this, result,
						ServerResponseCode.FAILED);
				return;
			} else if (ServerResponseCode.parseOf(result) == ServerResponseCode.NOMORE) {
				ccb.setCommResult(this, result,
						ServerResponseCode.NOMORE);
				return;
			} else if (ServerResponseCode.parseOf(result) == ServerResponseCode.SUCCESS) {
				ccb.setCommResult(this, result,
						ServerResponseCode.SUCCESS);
			} else {

				if ((result.length() > 0)) {
				
					Dao<UserToPersons, Integer> utop = getHelper(mcontext)
							.getUserToPersonsDao();
					@SuppressWarnings("unchecked")
					List<UserToPersons> datas =  
							UserToPersonsListJsonWrapper
							.getInstance(result,UserToPersonsListJsonWrapper.class).getMpps();

					if (datas.size()<1)
					{
						Log.e(LOG_TAG,"server is error. The size of user to person is zero.");
						ccb.setCommResult(this, result,
								ServerResponseCode.FAILED);
						return ;
					}

					//add all to original 
					List<UserToPersons> templist = utop.queryBuilder().where().eq("username", username).query();
					Set<String> original = new HashSet<String>();
					for (UserToPersons temp:templist)
						original.add(temp.getPersonID());
					
					List<Integer> changed = new ArrayList<Integer>();
					
					//loop all server record
					for (UserToPersons data:datas)
					{
						// the server has the person, so remove the original
						original.remove(data.getPersonID());
						List<UserToPersons> utoplist = utop.queryBuilder().where().eq("username", data.getUsername()).and().eq("personID", data.getPersonID()).query();
						if (utoplist.size() == 1) //local has same person
						{
							//if u2p modified data has changed means the personprofile has changed.
							//so we need to update personprofile as well
							if (utoplist.get(0).getModified().equals(data.getModified()))
							{
								//escape, server and local are same.
							}else
							{
								data.setId(utoplist.get(0).getId());
								utop.createOrUpdate(data);
								changed.add(data.getId());
							}
						}else if (utoplist.size() == 0)
						{
							utop.create(data);
							changed.add(data.getId());
						}else
						{
							//error condition
							DeleteBuilder<UserToPersons, Integer> deleteBuilder = utop.deleteBuilder();
							deleteBuilder.where().eq("username", data.getUsername()).and().eq("personID", data.getPersonID());
							deleteBuilder.delete();
							utop.create(data);
							changed.add(data.getId());
						}
						Log.i(LOG_TAG, "one "+data.getUsername()+" to "+data.getPersonID()+" has inserted.");						
					}
					
					//The left is not on server, so these should be deleted on local as well.
					for (String org:original)
					{
						DeleteBuilder<UserToPersons, Integer> deleteBuilder = utop.deleteBuilder();
						deleteBuilder.where().eq("username", username).and().eq("personID", org);
						deleteBuilder.delete();
					}

					Log.i(LOG_TAG,"PersonProfileDownloadTask run");		
					
					for (UserToPersons data:datas)
					{
						
						//download profile for share
						Dao<PersonProfile, Integer> ppdao = getHelper(mcontext)
								.getPersonProfileDao();
						List<PersonProfile> pps=ppdao.queryBuilder().where().
								eq("personID", data.getPersonID())
							.query();
						if (pps.size()==0)
						{
							BasicCommCallback ppccb = new BasicCommCallback();
							PersonProfileDownloadTask pdown = new
									PersonProfileDownloadTask(data.getPersonID(), 
											mcontext, ppccb);
							HealthThreadPool.getInstance().execute(pdown);
					
						}else
						{
							if (!changed.contains(Integer.valueOf(data.getId())))
							{
								continue;
							}else
							{
								BasicCommCallback ppccb = new BasicCommCallback();
								PersonProfileDownloadTask pdown = new
										PersonProfileDownloadTask(data.getPersonID(), 
												mcontext, ppccb);
								HealthThreadPool.getInstance().execute(pdown);
							}							
						}						
						
					}
					Log.i(LOG_TAG,"User task return.");
					ccb.setCommResult(this, result,
							ServerResponseCode.SUCCESS);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			ccb.setCommResult(this, result,
					ServerResponseCode.FAILED);
		}
		
	}

}